package com.bss.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.model.DataModel;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;

import com.andy.basics.Constants;
import com.andy.basics.Service;
import com.bss.dao.AdmissionDao;
import com.bss.dao.AttendentDao;
import com.bss.model.Admission;
import com.bss.model.Attendent;
import com.bss.model.CurrentAttendent;
import com.bss.model.Passport;
import com.bss.service.CurrentAttendentService;
import com.bss.service.IdGenerationService;

@Controller
@Scope("request")
public class CurrentAttendentController extends com.andy.basics.Controller<CurrentAttendent> {

	private static final String CLASS = CurrentAttendentService.class.getName();

	private static final Logger DEBUG = Logger.getLogger(Constants.DEBUG_KEY + CurrentAttendentController.CLASS);

	private static final Logger AUDIT = Logger.getLogger(Constants.AUDIT_KEY + CurrentAttendentController.CLASS);

	private static final Logger ERROR = Logger.getLogger(Constants.ERROR_KEY + CurrentAttendentController.CLASS);

	@Autowired
	private IdGenerationService idGenerationService;

	@Autowired
	private CurrentAttendentService currentAttendentService;

	@Autowired
	private AttendentDao attendentDao;

	@Autowired
	private AdmissionDao admissionDao;

	@Override
	public CurrentAttendent create() {
		CurrentAttendent ca = new CurrentAttendent();
		ca.getAttendent().setPassport(new Passport());
		return ca;
	}

	@Override
	public Service<CurrentAttendent> getService() {
		return this.currentAttendentService;
	}

	@Override
	@Transactional
	public String add() {
		if (this.getAdmission().getPatient().getId() != 0) {

			if (!this.getValidator().validate(this.getModel().getAttendent(), this.getMessageHandler())) {
				CurrentAttendentController.DEBUG.debug("Attendent is not valid !");
				this.setError(true);
				this.setErrors(null);
				return null;
			}

			for (CurrentAttendent currentAttendent : this.currentAttendentService.getModels()) {
				if (currentAttendent.getAttendent().getName().equals(this.getModel().getAttendent().getName())) {
					this.setError(true);
					this.setErrors(new ArrayList<String>());
					this.getErrors().add("Attendent " + this.getModel().getAttendent().getName() + " is already present !");
					return null;
				}
			}

			List<Attendent> attendents = this.attendentDao.findAllForPatient(this.getAdmission().getPatient(), "name='"
					+ this.getModel().getAttendent().getName() + "'");
			if ((attendents != null) && (attendents.size() > 0)) {
				Attendent attendent = attendents.get(0);
				attendent.setDateOfBirth(this.getModel().getAttendent().getDateOfBirth());
				this.getModel().setAttendent(attendent);
			}
			this.getModel().setAdmission(this.admissionDao.findById(this.getAdmission().getId()));
			this.getModel().getAttendent().setPatient(this.getAdmission().getPatient());
			this.getModel().setDateOfArrival(new Date());
			this.getModel().setDateOfLeave(null);
			super.add();
			this.setError(false);
		}
		return null;
	}

	@Override
	public String update() {
		this.setError(false);
		if (!this.getValidator().validate(this.getModel().getAttendent(), this.getMessageHandler())) {
			CurrentAttendentController.DEBUG.debug("Attendent is not valid !");
			this.setError(true);
			this.setErrors(null);
		}
		if ("Passport".equalsIgnoreCase(this.getModel().getAttendent().getIdCardType().getName())) {
			if (!this.getValidator().validate(this.getModel().getAttendent().getPassport(), this.getMessageHandler())) {
				CurrentAttendentController.DEBUG.debug("Attendent is not valid !");
				this.setError(true);
				this.setErrors(new ArrayList<String>());
				this.getErrors().add("Passport is not valid");
			}
		} else {
			if ((this.getModel().getAttendent().getIdCardNumber() == null)
					|| (this.getModel().getAttendent().getIdCardNumber().length() == 0)) {
				this.getMessageHandler().addMessage("idCardnumber", "ID Card number must be specified");
				this.setError(true);
				this.setErrors(new ArrayList<String>());
				this.getErrors().add("ID is not valid");
			}
		}
		if (this.isError()) {
			return null;
		}
		return super.update();
	}

	public Admission getAdmission() {
		return this.currentAttendentService.getAdmission();
	}

	public DataModel admissions(final Object patientName) {
		if (patientName == null) {
			return null;
		}
		return this.idGenerationService.getActiveAdmissionData(patientName.toString());
	}

	public DataModel attendents(final Object attendentName) {
		if ((attendentName == null) || (this.getAdmission().getPatient().getId() == 0)) {
			return null;
		}
		return this.currentAttendentService.getAttendentsData(this.getAdmission().getPatient(), attendentName.toString());
	}

	public String selectAdmission() {

		Admission admission = (Admission) this.idGenerationService.getData().getRowData();
		this.currentAttendentService.selectAdmission(admission);
		return null;
	}

	public String selectAttendent() {
		if (this.currentAttendentService.getSelectableCurrentAttendent().getRowIndex() < 0) {
			return null;
		}
		Attendent attendent = (Attendent) this.currentAttendentService.getSelectableCurrentAttendent().getRowData();
		this.getModel().setAttendent(attendent);
		return null;
	}

	@Override
	public String select() {
		super.select();
		if (this.getModel().getAttendent().getPassport() == null) {
			this.getModel().getAttendent().setPassport(new Passport());
		}
		return null;
	}

	public void exitAttendent() {
		this.currentAttendentService.exitAttendent(this.getDate());
	}

	public DataModel getAllAttendents() {
		return this.currentAttendentService.getAllAttendentsDataModel();
	}

	public void checkin() {
		String status = this.currentAttendentService.checkin(new Date());
		if (!Constants.SUCCESS.equals(status)) {
			CurrentAttendentController.AUDIT.info("Failed to checkin attendent: " + status);
			this.setErrors(new ArrayList<String>());
			this.getErrors().add("Failed to checkin attendent: " + status);
			this.setError(true);
			return;
		}
		this.setError(false);
	}
}
